#pragma once

#include <iostream>
#include <pthread.h>
#include <string>
#include <functional>

template<class T>
using fun_t = std::function<void(T)>;

template<class T>
class Thread
{
public:
    Thread(const std::string& Tthreadname,fun_t<T> func,T data)
    :_tid(0),_treadname(Tthreadname),_fnc(func),_isrunning(false),_data(data)
    {}
    static void* pthreadroute(void* args)
    {
        Thread* ts = static_cast<Thread*> (args);
        ts->_fnc(ts->_data);
        return nullptr;
    }
    bool Start()
    {

        int n = pthread_create(&_tid,nullptr,pthreadroute,this);
        if(n == 0)
        {
            _isrunning = true;
            return true;
        }
        else
        {
            return false;
        }
    }
    bool Join()
    {
        if(!Running())    return true;
        int  n = pthread_join(_tid,nullptr);
        if(n == 0)
        {
            _isrunning = false;
            return true;
        }
        else return false;
    }
    

    std::string Threadname()
    {
        return _treadname;
    }
    bool Running()
    {
        return _isrunning;
    }
    ~Thread(){}
private:
    pthread_t _tid;
    std::string _treadname;
    T _data;
    bool _isrunning;
    fun_t<T> _fnc;
};